﻿using RingBuffer;
using System;
using System.Threading.Tasks;

namespace kratos {
/// <summary>
/// 外部日志接口
/// </summary>
public interface ILogger {
  void Debug(string log);
  void Info(string log);
  void Warn(string log);
  void Fail(string log);
  void Fatal(string log);
}
/// <summary>
/// 本地服务接口
/// </summary>
public interface IService {
  ulong UUID { get; }
  uint ID { get; }
  void OnTick(long ms);
}
/// <summary>
/// RPC接口
/// </summary>
public interface IRpc {
  /// <summary>
  /// 初始化
  /// </summary>
  /// <param name="logger">外部日志接口</param>
  /// <returns></returns>
  bool Initialize(ILogger logger);
  /// <summary>
  /// 是否已经连接到远程主机
  /// </summary>
  bool IsConnected { get; }
  /// <summary>
  /// 连接远程主机
  /// </summary>
  /// <param name="host">地址</param>
  /// <param name="port">端口</param>
  /// <param name="timeout">连接超时，毫秒</param>
  /// <returns>成功或失败，true或false</returns>
  Task<bool> Connect(string host, int port, long timeout);
  /// <summary>
  /// 重连
  /// </summary>
  /// <returns>成功或失败，true或false,
  /// 设置AutoReconnect为true时调用这个方法将返回false</returns>
  Task<bool> Reconnect();
  /// <summary>
  /// 关闭连接，如果设置了AutoConnect为true将触发自动重连
  /// </summary>
  void Close();
  /// <summary>
  /// 在逻辑主循环内调用
  /// </summary>
  void Update();
  /// <summary>
  /// 上次运行Update时的时间戳，毫秒
  /// </summary>
  long Tick { get; }
  /// <summary>
  /// 是否使用Tick来代替真实时间戳，可以减少获取系统时间戳的次数，但是会有一定的误差，但最大误差不超过一帧
  /// </summary>
  bool UseTickAsTimestamp {
    get;
    set;
  }
  /// <summary>
  /// 是否开启自动重连
  /// </summary>
  bool AutoReconnect {
    get;
    set;
  }
  /// <summary>
  /// 自动重连的间隔，毫秒
  /// </summary>
  long AutoReconnectIntvalMS {
    get;
    set;
  }
}

/// <summary>
/// 远程服务运行时出现错误
/// </summary>
public class RpcPeerErrorException : Exception {
  public RpcPeerErrorException(string message) : base(message) {}
  public RpcPeerErrorException() {}
  public override string Message {
    get { return base.Message; }
  }
}

/// <summary>
/// 远程服务未找到
/// </summary>
public class RpcPeerMethodNotFoundException : Exception {
  public RpcPeerMethodNotFoundException(string message) : base(message) {}
  public RpcPeerMethodNotFoundException() {}
  public override string Message {
    get { return base.Message; }
  }
}

/// <summary>
/// 远程调用超时
/// </summary>
public class RpcCallTimeoutException : Exception {
  public RpcCallTimeoutException(string message) : base(message) {}
  public RpcCallTimeoutException() {}
  public override string Message {
    get { return base.Message; }
  }
}

}
